package weeny.pre.display;

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import javax.swing.Box;
import javax.swing.JScrollPane;

import prefuse.Visualization;
import prefuse.util.FontLib;
import prefuse.visual.EdgeItem;
import prefuse.visual.NodeItem;
import prefuse.visual.VisualItem;
import weeny.pre.face.PreJTable;
import weeny.pre.util.Marker;

/**
 * Display that wraps Marker and provides an interface for it.
 * 
 * It has one extra control tab called MARKER_TAB.
 * 
 * @author weeny
 *
 */
public class MarkerDisplay extends BaseUIDisplay{
	
	public static final String MARKER_TAB = "Marker";
	public Marker marker = null;
	
	public MarkerDisplay(Visualization vis){
		super(vis);
		marker = new Marker(getVisualization());
		setDragControl(true);
		setHighQuality(true);
	}
	public MarkerDisplay() {
		marker = new Marker(getVisualization());
		setDragControl(true);
		setHighQuality(true);
	}
	
	/**
	 * Get the marker for further control
	 */
	public Marker getMarker(){
		return marker;
	}
	
	/**
	 * Set the depth of the item, as long as it is managered by Marker.
	 * The item with bigger depth will cover the ones with smaller one.
	 * If they are equal, it depends on the orders they are added.
	 * 
	 * @param item the item to be set depth
	 * @param depth the depth value
	 */
	public void setDepth(VisualItem item, int depth){
		marker.setDepth(item, depth);
	}
	/**
	 * Draw a text string on the display.
	 *
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 */
	public VisualItem drawString(String text, Point2D pos, int color, float size){
		VisualItem vi = marker.drawText(pos, text, color, size);
		vi.setFont(FontLib.getFont("Helvetica", 10));
		return vi;
	}
	/**
	 * Draw a line on the display.
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 */
	public EdgeItem drawLine(Line2D line, int color, float size){
		return marker.drawLine(line, color, size);
	}
	/**
	 * Draw a arrow on the display.
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 */
	public EdgeItem drawArrow(Line2D line, int color, float size){
		return marker.drawArrow(line, color, size);
	}
	/**
	 * Draw a graph node in the display. It is different with drawingShape,
	 * because the return value will be used to create graph edges. 
	 * By draging the graph node, you can move all the edges connecting to it.
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 */
	public NodeItem drawGraphNode(Point2D position, double size, int shape, int fillColor){
		return (NodeItem) drawShape(position, size, shape, fillColor);
	}
	/**
	 * Drawing graph edge in the display. It is different with drawingLine, you need to call
	 * drawGraphNode before you can drawGraphEdge. But you can directly draw line by giving
	 * two end positions. 
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 */
	public EdgeItem drawGraphEdge(NodeItem s, NodeItem t, int color, float width){
		return marker.drawEdge(s, t, color, width, false);
	}
	/**
	 * Draw a shape at the given position. the shape is defined in <code>Constants<code>
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 */
	public VisualItem drawShape(Point2D position, double size, int shape, int fillColor){
		return marker.drawNode(position, shape, fillColor, size);
	}
	
	/**
	 * Fill a curved region by using a given color.
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 * @param xyxyxy a float array with xyxy... orders of the points on the curve 
	 */
	public VisualItem fillCurve(float[] xyxyxy, int fillColor){
		VisualItem item = drawCurve(xyxyxy, fillColor, 1);
		item.setFillColor(fillColor);
		return item;
	}
	/**
	 * Fill a polygon region by using a given color.
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 * @param xyxyxy a float array with xyxy... orders of the points on the curve 
	 */
	public VisualItem fillPolygon(float[] xyxyxy, int fillColor){
		VisualItem item = drawPolyline(xyxyxy, fillColor, 1);
		item.setFillColor(fillColor);
		return item;
	}
	
	/**
	 * Draw a polyline by using a given color
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 * @param xyxyxy an array with xyxy... orders of the points on the curve 
	 */
	public VisualItem drawPolyline(float[] xyxyxy, int strokeColor, float size){
		return marker.drawPolyline(xyxyxy, strokeColor, size);
	}
	/**
	 * Draw a curve by using a given color
	 * 
	 * The color is defined in <code>ColorLib<code>, 
	 * There are also some predefined colors in <code>Pre<code>
	 * @param xyxyxy an array with xyxy... orders of the points on the curve 
	 */
	public VisualItem drawCurve(float[] xyxyxy, int strokeColor, float size){
		return marker.drawCurve(xyxyxy, strokeColor, size);
	}
	
	/**
	 * override to add two more controls
	 * 1) load/save data buttons
	 * 2) show dummy node checkbox
	 */
	@Override
	public void showIODisplayTab() {
		addWidget(IO_DISPLAY_TAB, marker.createLoadSaveBox(null));
		super.showIODisplayTab();
		addWidget(IO_DISPLAY_TAB, marker.createShowDummyCheck());
	}
	/**
	 * an extra tab showing information about the items in markers
	 */
	public void showVisualMarkerTab(){
		
		addWidget(MARKER_TAB, marker.createRendererControl());
		
		PreJTable table = marker.createEdgeControlTable();
		JScrollPane pane = table.scrollView("Edge Table", TABLE_DIM);
		addWidget(MARKER_TAB, pane);
		
		//adding strut
		addWidget(MARKER_TAB, Box.createVerticalStrut(10));
		
		table = marker.createNodeControlTable();
		pane = table.scrollView("Node Table", TABLE_DIM);
		addWidget(MARKER_TAB, pane);
		
		setControlTabsVisible(true);
	}
}